//
//  IDODashboardView.m
//  IDODashboardView
//
//  Created by 卓勇 on 2017/3/3.
//  Copyright © 2017年 idozhuoyong. All rights reserved.
//

#import "IDODashboardView.h"
#import "IDONumberJumpUitls.h"

#define RGBColor(R, G, B)       [UIColor colorWithRed:R/255.0 green:G/255.0 blue:B/255.0 alpha:1.0]
#define KAngleToradian(angle) (M_PI / 180.0 * (angle)) // 角度转弧度

/**
 参考：http://www.jianshu.com/p/9f80840175db
 */
@interface IDODashboardView ()

@property (nonatomic, assign) CGFloat realLineRadius; // 实线半径
@property (nonatomic, assign) CGFloat dottedLineRadius; // 虚线半径
@property (nonatomic, assign) CGFloat cursorRadius; // 光标半径

@property (nonatomic, assign) CGFloat startAngle; // 起始角度
@property (nonatomic, assign) CGFloat endAngle; // 结束角度

@property (nonatomic, assign) CGFloat realLineWidth; // 实线线宽
@property (nonatomic, assign) CGFloat dottedLineWidth; // 虚线线宽

@property (nonatomic, strong) CAShapeLayer *realLineBackgroundLayer; // 实线背景弧形
@property (nonatomic, strong) CAShapeLayer *dottedLineBackgroundLayer; // 虚线背景弧形
@property (nonatomic, strong) CAShapeLayer *realLineLayer; // 实线前景弧形
@property (nonatomic, strong) CAShapeLayer *dottedLineLayer; // 虚线前景弧形

@property (nonatomic, strong) UIImageView *outerCursorImageView; // 外部游标
@property (nonatomic, strong) UIImageView *innerCursorImageView; // 内部游标

// @property (nonatomic, assign) CGFloat animationDuration; // 动画时间

// @property (nonatomic, assign) CGFloat minValue;
// @property (nonatomic, assign) CGFloat maxValue;
// @property (nonatomic, assign) CGFloat currentValue;
//
// @property (nonatomic, strong) UILabel *titleLabel;
// @property (nonatomic, strong) UILabel *numberLabel;
// @property (nonatomic, strong) UILabel *detailInfoLabel;

@end

@implementation IDODashboardView

- (instancetype)initWithFrame:(CGRect)frame {
    self = [super initWithFrame:frame];
    
    if (self) {
        self.backgroundColor = [UIColor clearColor];
        
        self.minValue = 0;
        self.maxValue = 100;
        //self.currentValue = 80;
        
        self.realLineWidth = 2; // 实线线宽
        self.dottedLineWidth = 2; // 虚线线宽
        self.startAngle = -200; // 起始角度
        self.endAngle = 20; // 结束角度
        self.realLineRadius = ((CGRectGetWidth(self.bounds) - 10) / 2.0); // 实线半径
        self.dottedLineRadius = ((CGRectGetWidth(self.bounds) - 25) / 2.0); // 虚线半径
        self.cursorRadius = 3.5; // 光标半径
        
        self.animationDuration = 3; // 动画时间
        
        // 初始化仪表盘
        [self initDashboardBackground];
        
        // init Other View
        [self initOtherView];
        
        // 根据当前值刷新仪表盘
        // [self refreshDashboard:self.currentValue];
    }
    
    return self;
}

#pragma mark - init method
/**
 初始化仪表盘
 */
- (void)initDashboardBackground {
    UIColor *strokeUIColor = RGBColor(122, 208, 213);
    
    // 实线背景圆形
    UIBezierPath *realLineBackgroundBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0)
                                                                                radius:self.realLineRadius
                                                                            startAngle:KAngleToradian(self.startAngle)
                                                                              endAngle:KAngleToradian(self.endAngle)
                                                                             clockwise:YES]; // clockwise表示画圆弧的方向
    
    self.realLineBackgroundLayer = [CAShapeLayer layer];
    self.realLineBackgroundLayer.frame = self.bounds;
    self.realLineBackgroundLayer.fillColor = [UIColor clearColor].CGColor;
    self.realLineBackgroundLayer.strokeColor = strokeUIColor.CGColor;
    self.realLineBackgroundLayer.lineCap = kCALineCapRound;
    self.realLineBackgroundLayer.lineWidth = self.realLineWidth;
    self.realLineBackgroundLayer.path = [realLineBackgroundBezierPath CGPath];
    [self.layer addSublayer:self.realLineBackgroundLayer];
    
    // 虚线背景圆形
    UIBezierPath *dottedLineBackgroundBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0)
                                                                                  radius:self.dottedLineRadius
                                                                              startAngle:KAngleToradian(self.startAngle)
                                                                                endAngle:KAngleToradian(self.endAngle)
                                                                               clockwise:YES]; // clockwise表示画圆弧的方向
    
    CGFloat dottedLineLength = 1; // 虚线长度
    CGFloat dottedLineSpacing = 5; // 虚线间距
    self.dottedLineBackgroundLayer = [CAShapeLayer layer];
    self.dottedLineBackgroundLayer.frame = self.bounds;
    self.dottedLineBackgroundLayer.fillColor = [UIColor clearColor].CGColor;
    self.dottedLineBackgroundLayer.strokeColor = strokeUIColor.CGColor;
    self.dottedLineBackgroundLayer.lineCap = kCALineCapRound;
    self.dottedLineBackgroundLayer.lineWidth = self.dottedLineWidth;
    [self.dottedLineBackgroundLayer setLineJoin:kCALineJoinRound]; // 线条连接样式
    [self.dottedLineBackgroundLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithFloat:dottedLineLength], [NSNumber numberWithFloat:dottedLineSpacing], nil]];
    self.dottedLineBackgroundLayer.path = [dottedLineBackgroundBezierPath CGPath];
    [self.layer addSublayer:self.dottedLineBackgroundLayer];
}

- (void)initCursorView {
    if (self.outerCursorImageView) {
        [self.outerCursorImageView removeFromSuperview];
        self.outerCursorImageView = nil;
    }
    
    if (self.innerCursorImageView) {
        [self.innerCursorImageView removeFromSuperview];
        self.innerCursorImageView = nil;
    }
    
    [self addSubview:self.outerCursorImageView];
    [self addSubview:self.innerCursorImageView];
}

- (void)initOtherView {
    // add titleLabel
    [self addSubview:self.titleLabel];
    
    // add numberLabel
    [self addSubview:self.numberLabel];
    
    // add detailLabel
    [self addSubview:self.detailInfoLabel];
}

#pragma mark - draw dashboard method
- (void)refresh {
    [self refreshDashboard:self.currentValue];
}

- (void)refreshDashboard:(CGFloat)currentValue {
    // 初始化光标
    [self initCursorView];
    
    // Layer
    if (self.dottedLineLayer) {
        [self.dottedLineLayer removeFromSuperlayer];
    }
    
    if (self.realLineLayer) {
        [self.realLineLayer removeFromSuperlayer];
    }
    
    // 控制范围
    if (currentValue > self.maxValue) {
        currentValue = self.maxValue;
    }
    if (currentValue <= self.minValue) {
        currentValue = self.minValue;
    }
    
    // 百分比
    CGFloat percent = (currentValue - self.minValue) / (self.maxValue - self.minValue);
    
    // 当前角度
    CGFloat currentAngle = self.startAngle + (fabs(self.endAngle - self.startAngle) * percent);
    
    // 前景弧形绘制
    [self dashboardDrawPercent:percent startAngle:self.startAngle endAngle:currentAngle];
}

- (void)dashboardDrawPercent:(CGFloat)percent startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle {
    CGFloat animationDuration = self.animationDuration * percent;
    // NSLog(@"%f --- %f --- %f", startAngle, endAngle, animationDuration);
    
    /*
     // 设置动画属性
     CAKeyframeAnimation *outerCursorPathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
     outerCursorPathAnimation.calculationMode = kCAAnimationPaced;
     outerCursorPathAnimation.fillMode = kCAFillModeForwards;
     outerCursorPathAnimation.removedOnCompletion = NO;
     outerCursorPathAnimation.duration = animationDuration; // 动画时间
     outerCursorPathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
     outerCursorPathAnimation.repeatCount = 1;
     
     // 设置动画路径
     CGMutablePathRef outerCursorPath = CGPathCreateMutable();
     CGPathAddArc(outerCursorPath, NULL, CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0, self.realLineRadius, KAngleToradian(startAngle), KAngleToradian(endAngle), NO);
     outerCursorPathAnimation.path = outerCursorPath;
     CGPathRelease(outerCursorPath);
     
     // 外圈游标
     [self.outerCursorImageView.layer addAnimation:outerCursorPathAnimation forKey:@"moveMarker"];
     
     // 设置动画属性
     CAKeyframeAnimation *innerCursorPathAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
     innerCursorPathAnimation.calculationMode = kCAAnimationPaced;
     innerCursorPathAnimation.fillMode = kCAFillModeForwards;
     innerCursorPathAnimation.removedOnCompletion = NO;
     innerCursorPathAnimation.duration = animationDuration; // 动画时间
     innerCursorPathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
     innerCursorPathAnimation.repeatCount = 1;
     
     // 设置动画路径
     CGMutablePathRef innerCursorPath = CGPathCreateMutable();
     CGPathAddArc(innerCursorPath, NULL, CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0, self.dottedLineRadius - 10, KAngleToradian(startAngle), KAngleToradian(endAngle), NO);
     innerCursorPathAnimation.path = innerCursorPath;
     CGPathRelease(innerCursorPath);
     
     // 内圈游标
     // 这种方式在超过180°之后不会顺时针旋转
     [UIView beginAnimations:nil context:nil];
     [UIView setAnimationDuration:10];
     [UIView setAnimationDelegate:self];
     self.innerCursorImageView.transform = CGAffineTransformRotate(self.innerCursorImageView.transform, KAngleToradian(endAngle - startAngle));
     [UIView commitAnimations];
     [self.innerCursorImageView.layer addAnimation:innerCursorPathAnimation forKey:@"moveMarker"];
     */
    
    // 实线弧形
    UIBezierPath *realLineBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0)
                                                                      radius:self.realLineRadius
                                                                  startAngle:KAngleToradian(startAngle)
                                                                    endAngle:KAngleToradian(endAngle)
                                                                   clockwise:YES]; // clockwise表示画圆弧的方向
    
    self.realLineLayer = [CAShapeLayer layer];
    self.realLineLayer.frame = self.bounds;
    self.realLineLayer.fillColor = [UIColor clearColor].CGColor;
    self.realLineLayer.strokeColor = [UIColor whiteColor].CGColor;
    self.realLineLayer.lineCap = kCALineCapRound;
    self.realLineLayer.lineWidth = self.realLineWidth;
    self.realLineLayer.path = [realLineBezierPath CGPath];
    [self.layer addSublayer:self.realLineLayer];
    
    // 虚线弧形
    UIBezierPath *dottedLineBezierPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0)
                                                                        radius:self.dottedLineRadius
                                                                    startAngle:KAngleToradian(startAngle)
                                                                      endAngle:KAngleToradian(endAngle)
                                                                     clockwise:YES]; // clockwise表示画圆弧的方向
    
    CGFloat dottedLineLength = 1; // 虚线长度
    CGFloat dottedLineSpacing = 5; // 虚线间距
    self.dottedLineLayer = [CAShapeLayer layer];
    self.dottedLineLayer.frame = self.bounds;
    self.dottedLineLayer.fillColor = [UIColor clearColor].CGColor;
    self.dottedLineLayer.strokeColor = [UIColor whiteColor].CGColor;
    self.dottedLineLayer.lineCap = kCALineCapRound;
    self.dottedLineLayer.lineWidth = self.dottedLineWidth;
    [self.dottedLineLayer setLineJoin:kCALineJoinRound]; // 线条连接样式
    [self.dottedLineLayer setLineDashPattern:[NSArray arrayWithObjects:[NSNumber numberWithFloat:dottedLineLength], [NSNumber numberWithFloat:dottedLineSpacing], nil]];
    self.dottedLineLayer.path = [dottedLineBezierPath CGPath];
    [self.layer addSublayer:self.dottedLineLayer];
    
    // 动画
    // 进度条动画
    [self drawPregressLayerAnimation:self.realLineLayer duration:animationDuration];
    [self drawPregressLayerAnimation:self.dottedLineLayer duration:animationDuration];
    
    // 游标动画
    [self moveCursorLayerAnimation:self.outerCursorImageView.layer duration:animationDuration radius:self.realLineRadius startAngle:startAngle endAngle:endAngle];
    [self moveCursorLayerAnimation:self.innerCursorImageView.layer duration:animationDuration radius:(self.dottedLineRadius - 10) startAngle:startAngle endAngle:endAngle];
    
    // 游标旋转动画
    [self rotateViewAnimatio:self.innerCursorImageView duration:animationDuration byAngle:KAngleToradian(endAngle - startAngle)];
    
    // 数字跳动
    __weak typeof(self) __weakSelf = self;
    IDONumberJumpUitls *numberJumpUitls = [[IDONumberJumpUitls alloc] init];
   
    [numberJumpUitls jumpNumberWithDuration:animationDuration fromNumber:self.minValue toNumber:self.currentValue numberJumpBlock:^(double value) {
        __weakSelf.numberLabel.text = [NSString stringWithFormat:@"%.2f", value];
    }];
}

#pragma mark - animation method
- (void)rotateViewAnimatio:(UIView*)view duration:(CFTimeInterval)duration byAngle:(CGFloat)angle
{
    // 超过180°，需要采用这种方式
    [CATransaction begin];
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    animation.byValue = [NSNumber numberWithFloat:angle];
    animation.duration = duration;
    animation.removedOnCompletion = NO;
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    
    [CATransaction setCompletionBlock:^{
        view.transform = CGAffineTransformRotate(view.transform, angle);
    }];
    
    [view.layer addAnimation:animation forKey:@"rotateViewAnimated"];
    [CATransaction commit];
}

- (void)moveCursorLayerAnimation:(CALayer *)layer duration:(CFTimeInterval)duration radius:(CGFloat)radius startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle {
    // 设置动画属性
    CAKeyframeAnimation *animation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    animation.calculationMode = kCAAnimationPaced;
    animation.fillMode = kCAFillModeForwards;
    animation.removedOnCompletion = NO;
    animation.duration = duration; // 动画时间
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    animation.repeatCount = 1;
    
    // 设置动画路径
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddArc(path, NULL, CGRectGetWidth(self.bounds) / 2.0, CGRectGetHeight(self.bounds) / 2.0, radius, KAngleToradian(startAngle), KAngleToradian(endAngle), NO);
    animation.path = path;
    CGPathRelease(path);
    
    //
    [layer addAnimation:animation forKey:@"moveCursorLayerAnimation"];
}

- (void)drawPregressLayerAnimation:(CALayer *)layer duration:(CFTimeInterval)duration {
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = duration; // 动画时间
    animation.fromValue = [NSNumber numberWithInt:0];
    animation.toValue = [NSNumber numberWithInt:1];
    animation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    [layer addAnimation:animation forKey:@"drawPregressLayerAnimation"];
}

#pragma mark - setter and getter method
- (UIImageView *)outerCursorImageView {
    if (!_outerCursorImageView) {
        UIImageView *outerCursorImageView = [[UIImageView alloc] init];
        outerCursorImageView.backgroundColor = [UIColor clearColor];
        outerCursorImageView.layer.backgroundColor = [UIColor whiteColor].CGColor;
        outerCursorImageView.layer.shadowColor = [UIColor whiteColor].CGColor;
        outerCursorImageView.layer.shadowOffset = CGSizeMake(0, 0);
        outerCursorImageView.layer.shadowRadius = self.cursorRadius; // 阴影的半径
        outerCursorImageView.layer.shadowOpacity = 1; // 阴影的不透明度
        outerCursorImageView.layer.masksToBounds = NO;
        outerCursorImageView.layer.cornerRadius = self.cursorRadius;
        outerCursorImageView.frame = CGRectMake(-200, -200, self.cursorRadius * 2, self.cursorRadius * 2);
        _outerCursorImageView = outerCursorImageView;
    }
    return _outerCursorImageView;
}

- (UIImageView *)innerCursorImageView {
    if (!_innerCursorImageView) {
        UIImageView *innerCursorImageView = [[UIImageView alloc] init];
        innerCursorImageView.image = [UIImage imageNamed:@"innerCursor"];
        innerCursorImageView.frame = CGRectMake(-200, -200, innerCursorImageView.image.size.width, innerCursorImageView.image.size.height);
        // 旋转成和仪表盘角度一致
        innerCursorImageView.transform = CGAffineTransformRotate(innerCursorImageView.transform, KAngleToradian(self.startAngle + 90));
        _innerCursorImageView = innerCursorImageView;
    }
    return _innerCursorImageView;
}

- (UILabel *)titleLabel {
    if (!_titleLabel) {
        CGFloat screenScale = CGRectGetWidth(self.bounds) / 295.0;
        CGFloat spacing = screenScale * 50;
        CGFloat width = screenScale * 140;
        CGFloat height = screenScale * 30;
        
        UILabel *titleLabel = [[UILabel alloc] init];
        titleLabel.frame = CGRectMake((CGRectGetWidth(self.bounds) - width) / 2.0, CGRectGetHeight(self.bounds) / 2.0 - self.dottedLineRadius + spacing, width, height);
        titleLabel.text = @"信用极好";
        titleLabel.textAlignment = NSTextAlignmentCenter;
        titleLabel.font = [UIFont systemFontOfSize:20];
        titleLabel.adjustsFontSizeToFitWidth = YES;
        titleLabel.textColor = [UIColor whiteColor];
        // titleLabel.backgroundColor = [UIColor lightGrayColor];
        _titleLabel = titleLabel;
    }
    return _titleLabel;
}

- (UILabel *)numberLabel {
    if (!_numberLabel) {
        CGFloat screenScale = CGRectGetWidth(self.bounds) / 295.0;
        CGFloat width = screenScale * 220;
        CGFloat height = screenScale * 70;
        
        UILabel *numberLabel = [[UILabel alloc] init];
        numberLabel.frame = CGRectMake((CGRectGetWidth(self.bounds) - width) / 2.0, CGRectGetMaxY(self.titleLabel.frame), width, height);
        numberLabel.text = @"731";
        numberLabel.textAlignment = NSTextAlignmentCenter;
        numberLabel.font = [UIFont boldSystemFontOfSize:37];
        numberLabel.adjustsFontSizeToFitWidth = YES;
        numberLabel.textColor = [UIColor whiteColor];
        // numberLabel.backgroundColor = [UIColor lightGrayColor];
        _numberLabel = numberLabel;
    }
    return _numberLabel;
}

- (UILabel *)detailInfoLabel {
    if (!_detailInfoLabel) {
        CGFloat screenScale = CGRectGetWidth(self.bounds) / 295.0;
        CGFloat width = screenScale * 200;
        CGFloat height = screenScale * 30;
        
        UILabel *detailInfoLabel = [[UILabel alloc] init];
        detailInfoLabel.frame = CGRectMake((CGRectGetWidth(self.bounds) - width) / 2.0, CGRectGetMaxY(self.numberLabel.frame), width, height);
        detailInfoLabel.text = @"评估时间: 2017-02-06";
        detailInfoLabel.textAlignment = NSTextAlignmentCenter;
        detailInfoLabel.font = [UIFont systemFontOfSize:14];
        detailInfoLabel.adjustsFontSizeToFitWidth = YES;
        detailInfoLabel.textColor = RGBColor(165, 231, 232);
        // detailInfoLabel.backgroundColor = [UIColor lightGrayColor];
        _detailInfoLabel = detailInfoLabel;
    }
    return  _detailInfoLabel;
}

@end
